﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Description;
using System.ServiceModel;
using System.Collections.ObjectModel;
using System.ServiceModel.Channels;

namespace yule.Common.WCF
{
    /// <summary>
    /// 添加错误绑定
    /// IErrorHandler参考:http://www.cnblogs.com/webabcd/archive/2008/01/28/1056147.html
    /// </summary>
    [AttributeUsage(AttributeTargets.Class)]
    internal class ErrorHandlerBehaviorAttribute : Attribute, IErrorHandler, IServiceBehavior
    {
        /// <summary>
        /// 检查服务描述和服务宿主，以确认服务可以成功运行
        /// </summary>
        /// <param name="description"></param>
        /// <param name="serviceHostBase"></param>
        public void Validate(ServiceDescription description, ServiceHostBase serviceHostBase)
        {

        }

        /// <summary>
        /// 为契约增加自定义绑定参数
        /// </summary>
        /// <param name="description"></param>
        /// <param name="serviceHostBase"></param>
        /// <param name="endpoints"></param>
        /// <param name="parameters"></param>
        public void AddBindingParameters(ServiceDescription description, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection parameters)
        {

        }

        /// <summary>
        /// runtime时修改属性值或增加自定义扩展对象
        /// </summary>
        /// <param name="description"></param>
        /// <param name="host"></param>
        public void ApplyDispatchBehavior(ServiceDescription description, ServiceHostBase host)
        {
            using (IEnumerator<ChannelDispatcherBase> enumerator = host.ChannelDispatchers.GetEnumerator())
            {
                while (enumerator.MoveNext())
                {
                    ChannelDispatcher channelDispatcher = (ChannelDispatcher)enumerator.Current;
                    channelDispatcher.ErrorHandlers.Add(this);
                }
            }
        }

        public bool HandleError(Exception error)
        {
            return false;
        }

        public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
        {
            FaultException<ServiceException> faultException = new FaultException<ServiceException>(new ServiceException(error));
            MessageFault fault2 = faultException.CreateMessageFault();
            fault = Message.CreateMessage(version, fault2, faultException.Action);
        }

    }
}